﻿using System;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Contact.Enum;

namespace VNet.VisiSuite.Common.Helper
{
    public static class FileHelper
    {
        /// <summary>
        /// Build the folder path depends on the image type
        /// </summary>
        /// <param name="imageType">
        ///     <para>If this method called from client side, image type must be ImageType.AllImage</para>
        ///     <para>Other wise, image type must be the same with the entity (Fitting, Layline, Tags,...) </para>
        /// </param>
        /// <returns></returns>
        public static string BuildFolderPath(ImageType imageType)
        {
            string picturePath = Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures);
            string pathServer = ConfigurationManager.AppSettings["ImageFileLocation"];
            if (string.IsNullOrEmpty(pathServer))
                pathServer = string.Format(@"{0}\Template\", picturePath);

            string path;

            //Called from server side (each entity has its own folder location)
            if (imageType != ImageType.AllImage)
            {
                path = string.Format(@"{0}{1}\", pathServer, imageType.ToString());
            }
            else //Called from client side (all images are in the same folder)
            {
                path = ConfigurationManager.AppSettings["ImageURLPath"];
                if (string.IsNullOrEmpty(path))
                    path = string.Format(@"{0}\Template\", picturePath);

                //server and client in the same machine
                if (path.ToLower() == pathServer.ToLower())
                    path = string.Format(@"{0}\Temp\", picturePath);
            }


            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            return path;
        }

        public static void DeleteAllFilesInFolder()
        {
            var directory = new DirectoryInfo(BuildFolderPath(ImageType.AllImage));
            // TODO: Temporary solution
            if (directory.GetFiles().Any())
            {
                foreach (FileInfo file in directory.GetFiles())
                {
                    try { file.Delete(); }
                    catch (Exception) { }
                }
            }
        }

        public static string ConvertBitmapImage(byte[] rawData, string partNumber, string extension)
        {
            string path = BuildFolderPath(ImageType.AllImage);

            string randomStr = Path.GetRandomFileName().Replace(".", "");

            string imagePath = string.Format(FormatString.ImageUrlFormatWithRandomString, path, RemoveSpecialCharacter(partNumber), randomStr, extension);
            Image image = ImageHelper.ConvertByteArrayToImage(rawData);
            image.Save(imagePath);

            return imagePath;
        }

        private static ImageCodecInfo GetEncoderInfo(ImageFormat format)
        {
            return ImageCodecInfo.GetImageDecoders().SingleOrDefault(c => c.FormatID == format.Guid);
        }

        public static string Resolution(Bitmap bitmap, string extension, string imageName)
        {
            if (bitmap == null)
                return null;

            string path = BuildFolderPath(ImageType.AllImage);

            string rStr = Path.GetRandomFileName().Replace(".", "");
            string imagePath = string.Format(FormatString.ImageUrlFormatWithRandomString, path, RemoveSpecialCharacter(imageName), rStr, extension);
            using (var newBitmap = new Bitmap(bitmap))
            {
                newBitmap.SetResolution(96, 96);
                newBitmap.Save(imagePath, GetImageFormatFromExtension(extension));
            }
            return imagePath;
        }

        private static ImageFormat GetImageFormatFromExtension(string extension)
        {
            switch (extension.ToLower())
            {
                case "bmp":
                    return ImageFormat.Bmp;
                case "rmf":
                    return ImageFormat.Emf;
                case "exif":
                    return ImageFormat.Exif;
                case "gif":
                    return ImageFormat.Gif;
                case "ico":
                    return ImageFormat.Icon;
                case "jpg":
                case "jpeg":
                    return ImageFormat.Jpeg;
                case "tiff":
                    return ImageFormat.Tiff;
                case "wmf":
                    return ImageFormat.Wmf;
                case "png":
                default:
                    return ImageFormat.Png;
            }
        }

        public static Image GetHoseImage(string resouceUrl)
        {
            Assembly commonProjectAssembly = Assembly.GetExecutingAssembly();
            Stream manifestResourceStream = commonProjectAssembly.GetManifestResourceStream(resouceUrl);
            if (manifestResourceStream != null)
                return Image.FromStream(manifestResourceStream);

            return null;
        }

        public static string GetExtension(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName)) return null;

            var urls = fileName.Split('.');
            if (urls.Length == 0) return null;

            return urls[urls.Length - 1];
        }

        public static string RemoveSpecialCharacter(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return string.Empty;
            return Regex.Replace(fileName, "[^0-9a-zA-Z]+", "_");
        }

        public static string UploadImage(byte[] rawData, string partNumber, string extension, ImageType imageType)
        {
            if (rawData == null || rawData.Length == 0)
                return null;

            string path = BuildFolderPath(imageType);
            string fileName = RemoveSpecialCharacter(partNumber);

            string imageUrl = string.Format(FormatString.ImageUrlFormat, path, fileName, extension);
            Image image = ImageHelper.ConvertByteArrayToImage(rawData);
            if (image != null)
            {
                image.Save(imageUrl);
                return string.Format("{0}.{1}", fileName, extension);
            }
            return null;
        }

        public static void DeleteUploadedImage(string imageUrl, ImageType imageType)
        {
            string path = BuildFolderPath(imageType);

            FileInfo file = new FileInfo(string.Format("{0}{1}", path, imageUrl));
            try { file.Delete(); }
            catch (Exception) { }
        }
    }
}